package com.norma.netty.study.netty.simple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangchaofeng
 * @date 2020/10/3
 * @description netty服务端处理器，需要继承netty规定好的HandlerAdapter（规范）
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    //读取数据（可以读取客户端发送的消息）
    //ChannelHandlerContext 上下文对象，含有管道pipeline和通道channel,地址
    //msg 客户端发送的数据
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //应改写成非阻塞式处理
/*        System.out.println("server ctx =" + ctx);
        //将msg转成ByteBuf
        //ByteBuf 类似 Nio的ByteBuffer，性能更高
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("客户端发送的消息是：" + byteBuf.toString(StandardCharsets.UTF_8));
        System.out.println("客户端地址：" + ctx.channel().remoteAddress());*/
        //1.用户程序自定义普通任务,非阻塞
        ctx.channel().eventLoop().execute(() -> {
            //ByteBuf 类似 Nio的ByteBuffer，性能更高
            ByteBuf byteBuf = (ByteBuf) msg;
            System.out.println("客户端发送的消息是：" + byteBuf.toString(StandardCharsets.UTF_8));
            System.out.println("客户端地址：" + ctx.channel().remoteAddress());
        });
        //2.开启定时任务
        ctx.channel().eventLoop().schedule(() -> {
            //ByteBuf 类似 Nio的ByteBuffer，性能更高
            ByteBuf byteBuf = (ByteBuf) msg;
            System.out.println("客户端发送的消息是：" + byteBuf.toString(StandardCharsets.UTF_8));
            System.out.println("客户端地址：" + ctx.channel().remoteAddress());
        }, 5, TimeUnit.SECONDS);


    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //writeAndFlush 写入buffer并刷新
        ctx.writeAndFlush(Unpooled.copiedBuffer("Hello,beauty", CharsetUtil.UTF_8));
    }

    //处理异常
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //关闭通道
        ctx.close();
    }
}
